/*
 * @Author: 孟庆晨
 * @Date: 2021-06-04 20:08:51
 * @LastEditTime: 2023-02-07 14:48:41
 * @LastEditors: mengqingchen mengqc1995@163.com
 * @Description:axios 封装
 * @FilePath: \soso-mall-pc\src\utils\axios.js
 * 道法自然
 */
import axios from 'axios'
import { MessageReset } from '@/utils/resetMessage'
import store from '@/store'
import router from '../router'
import { getPath } from '@/utils/index'
// import showCodeMessage from '@/utils/code'
import encryDecObj from './encryption'

import { getDeviceId, getRequestId } from './deviceOrRequest'
import Cookies from 'js-cookie'

// 接口错误情况处理
const errorHandler = err => {
  // 从pendingRequest对象中移除请求
  removePendingRequest(err.config || {})
  if (axios.isCancel(err)) {
    console.log('已取消的重复请求：' + err.message)
  } else {
    // 添加异常处理
  }
  console.log(err)
  if (err.response && err.response.code) {
    MessageReset({
      message: err.response.code,
      type: 'error',
      duration: 5 * 1000
    })
  }
  return Promise.reject(err)
}

const service = axios.create({
  // import.meta.env.MODE === 'development' 来判断是否开发环境
  withCredentials: false, // cookie
  // baseURL: 'http://192.168.70.98:8888/',
  baseURL: import.meta.env.MODE === 'development' ? '/dev-api' : getPath()

  // timeout: 100000
})

const public_key =
  'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAi25NIkuorAtjV2VH/WcsBQco4D7UGgfJ9qpf75xoTMtPwVDWXqRh1fUHytbtfEqAGAPyZqzAz/uUe77oqBIUfmBD5Qn5CjLvg71+f6cAAJONwHEowWSmrrXDXzwmg2lTUFa+qyG4MKUT43zITlIAQsqplbM0wJ43AaMY1nzQCluWUhSZHYUDOf3vDfW54KjYMTZm9iytd6X9DqS1RMVPgKKL1zL802HpDSLqkFm7HQ+Zl7gPk5953wO+GkiMf0XQd9sB9/3OmVuo8lAJMYTPQ6BD+wDEPbleHX0atad/yOn+kDgq0n1JZkNf24Tm5t3TgLFQ6Wlu/GudpOwJwTVc1wIDAQAB'

// 自定义请求头
let hreaderData = {
  'X-HR-DEVICE-ID': getDeviceId(),
  'X-HR-CLIENT-TYPE': 'HR_SOSO_WEB',
  'X-HR-VERSION': '1.0.0',
  'X-HR-PLATFORM': 'web',
  'X-HR-LOAD-BALANCE': '192.168.4.42'
}
let getEncryDecObj = new encryDecObj()
// 定义全局存储变量des3key
let desKey = {} // 函数返回唯一的请求key

function getRequestKey(config) {
  let { method, url, params, data } = config
  return [method, url, JSON.stringify(params), JSON.stringify(data)].join('&')
}

// 添加请求信息
let pendingRequest = new Map()
function addPendingRequest(config) {
  let requestKey = getRequestKey(config)
  config.cancelToken =
    config.cancelToken ||
    new axios.CancelToken(cancel => {
      if (!pendingRequest.has(requestKey)) {
        pendingRequest.set(requestKey, cancel)
      }
    })
}

// 取消重复请求，移除重复请求信息
function removePendingRequest(config) {
  let requestKey = getRequestKey(config)
  if (pendingRequest.has(requestKey)) {
    // 如果是重复的请求，则执行对应的cancel函数
    let cancel = pendingRequest.get(requestKey)
    cancel(requestKey)
    // 将前一次重复的请求移除
    pendingRequest.delete(requestKey)
  }
}

service.interceptors.request.use(
  config => {
    // 检查是否存在重复请求，若存在则取消已发的请求
    removePendingRequest(config)
    // 把当前请求信息添加到pendingRequest对象中
    addPendingRequest(config)

    let requestId = getRequestId()
    const token = store.state.user.token

    if (token) {
      config.headers.Authorization = 'Bearer ' + token
    }
    if (config.data && config.data.post) {
      if (config.method === 'post') {
        config.data.post = null
        config.params = config.data
      }
    }
    if (config.requestBase) {
      config.baseURL = window.ipConfig.loginUrl
    }
    const requestData = config.data && JSON.parse(JSON.stringify(config.data))
    console.log(requestData, '请求数据', config.url)
    if (JSON.parse(import.meta.env.VITE_encryption_decryption)) {
      if (config.method === 'post') {
        // config.headers['Content-Type'] = 'text/plain'
        const result = getEncryDecObj.createEncryption(config.data, public_key, requestId)
        desKey[requestId] = result.interfaceVariable

        delete result.interfaceVariable
        config.data = { ...result, version: '1.0.0' }
      }
    }

    config.headers = Object.assign(config.headers, {
      ...hreaderData,
      'X-HR-REQUEST-ID': requestId
    })

    return config
  },
  error => {
    console.log(error)
    // return Promise.reject()
  }
)

service.interceptors.response.use(response => {
  // 从pendingRequest对象中移除请求
  removePendingRequest(response.config)

  // application/octet-stream
  // 只将请求结果的data字段返回(JSON格式处理)
  let resData
  if (typeof response.data === 'string' && /{/.test(response.data)) {
    try {
      resData = JSON.parse(response.data)
    } catch (e) {
      resData = response.data
    }
  } else {
    resData = response.data
  }
  // 如果自定义代码不是20000，则判断为错误.
  if (resData.code && resData.code != 200 && resData.code !== true) {
    // 50008: 非法token; 50012: 其他客户端已登录; '505': Token 已过期; 401资源认证失败
    if (resData.code == 505 || resData.code == 506 || resData.code == 401) {
      // to re-login

      Cookies.remove('Admin-Token')
      store.commit('user/SET_TOKEN', '')
      setTimeout(() => {
        router.replace({ path: '/homePage' })
      }, 1000)
    }

    MessageReset({
      message: resData.msg,
      type: 'error',
      duration: 5 * 1000
    })
    return Promise.reject(new Error(resData.msg || 'Error'))
  }
  if (resData.encryptType) {
    const requestId = resData.requestId
    const decData = getEncryDecObj.decrypt(resData, desKey[requestId])
    delete desKey[requestId]
    console.log(decData, '响应数据', response.config.url)
    return JSON.parse(import.meta.env.VITE_encryption_decryption) ? decData : resData
  }
  return resData
}, errorHandler)

export default service
